package com.wn.cleandemo.utils

import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageInfo
import android.util.Log
import com.wn.cleandemo.junk.JunkType
import com.wn.cleandemo.junk.bean.JunkCache
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.Collections
import java.util.HashMap

/**
 * @author huangzehui
 * @date 2024/10/10 13:28 周四
 * @description app 相关的工具类
 */
object AppUtil {

    private const val LOG_TAG = "app_util"

    // 应用包名的md5集合，key：包名 value：md5
    private val mPkgMd5Map = Collections.synchronizedMap(mutableMapOf<String,Long>())

    /**
     * 添加包名的md5到集合中
     *
     * @param pkg 包名
     * @param md5 md5
     */
    @JvmStatic
    fun putPkgMd5(pkg: String, md5: Long) {
        if (mPkgMd5Map.containsKey(pkg)) {
            return
        }
        mPkgMd5Map[pkg] = md5
    }

    /**
     * 获取 md5
     */
    @JvmStatic
    fun getPkgMd5(pkg: String): Long {
        if (mPkgMd5Map.containsKey(pkg)) {
            return mPkgMd5Map[pkg]!!
        }
        return 0
    }

    /**
     * 加载所有的安装应用的信息
     */
    @JvmStatic
    fun loadInstallApps(context: Context) {
        GlobalScope.launch(Dispatchers.IO) {
            // 包名进行 md5 加密的信息
            val installedPkgMd5List = mutableListOf<JunkCache>()

            loadAllInstallApp { packageInfo: PackageInfo ->
                installedPkgMd5List.add(getInstalledPkgMd5(context, packageInfo))
            }

            showLog("installedPkgMd5List = ${installedPkgMd5List}")
        }
    }

    /**
     * 获取JunkCache（包名通过md5加密的信息）
     */
    @JvmStatic
    private fun getInstalledPkgMd5(context: Context, packageInfo: PackageInfo): JunkCache {
        val info = JunkCache(null, JunkType.Type.J_Cache)

        val pkgName = packageInfo.packageName
        var md5 = getPkgMd5(pkgName)

        if (md5 == 0L) {
            md5 = Md5Util.encrypt(pkgName)
            putPkgMd5(pkgName, md5)
        }

        info.pkgMD5 = md5
        info.pkgName = pkgName
        info.appName = packageInfo.applicationInfo.loadLabel(context.packageManager).toString()
        return info
    }

    /**
     * 加载所有的已安装的应用
     *
     * @param callBack 每个安装应用信息的回调
     */
    @JvmStatic
    fun loadAllInstallApp(callBack: (packageInfo: PackageInfo) -> Unit) {
        val allInstallApp = getAllInstallApp()
        for (packageInfo in allInstallApp) {
            showLog("application info = ${packageInfo}")
            callBack.invoke(packageInfo)
        }
    }

    /**
     * 获取所有已安装的app
     */
    @JvmStatic
    @SuppressLint("QueryPermissionsNeeded")
    fun getAllInstallApp(): List<PackageInfo> {
        val context = ContextUtil.context

        val packageManager = context.packageManager

        val installedPackages = packageManager.getInstalledPackages(0)
        if (installedPackages.isEmpty()) {
            return emptyList()
        }

        return installedPackages
    }


    /**
     * 展示log
     *
     * @param msg 消息
     */
    @JvmStatic
    fun showLog(msg: String) {
        Log.d(LOG_TAG, msg)
    }
}